home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / polepos.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  16KB  |  554 lines

  1. #ifndef ROAD_CORE_INCLUDE
  2.  
  3. #include "driver.h"
  4. #include "vidhrdw/generic.h"
  5.  
  6. UINT8 *polepos_view_memory;
  7. UINT8 *polepos_road_memory;
  8. UINT8 *polepos_sprite_memory;
  9. UINT8 *polepos_alpha_memory;
  10.  
  11. /* modified vertical position built from three nibbles (12 bit)
  12.  * of ROMs 136014-142, 136014-143, 136014-144
  13.  * The value RVP (road vertical position, lower 12 bits) is added
  14.  * to this value and the upper 10 bits of the result are used to
  15.  * address the playfield video memory (AB0 - AB9).
  16.  */
  17. static UINT16 polepos_vertical_position_modifier[256];
  18.  
  19. static UINT16 view_hscroll;
  20. static UINT16 road_vscroll;
  21.  
  22. static const UINT8 *road_control;
  23. static const UINT8 *road_bits1;
  24. static const UINT8 *road_bits2;
  25.  
  26. static struct osd_bitmap *view_bitmap;
  27. static UINT8 *view_dirty;
  28.  
  29.  
  30. static void draw_road_core_8(struct osd_bitmap *bitmap, int sx, int sy, int dx, int dy);
  31. static void draw_road_core_16(struct osd_bitmap *bitmap, int sx, int sy, int dx, int dy);
  32.  
  33.  
  34. /***************************************************************************
  35.  
  36.   Convert the color PROMs into a more useable format.
  37.  
  38.   Pole Position has three 256x4 palette PROMs (one per gun)
  39.   and a lot ;-) of 256x4 lookup table PROMs.
  40.   The palette PROMs are connected to the RGB output this way:
  41.  
  42.   bit 3 -- 220 ohm resistor  -- RED/GREEN/BLUE
  43.         -- 470 ohm resistor  -- RED/GREEN/BLUE
  44.         -- 1  kohm resistor  -- RED/GREEN/BLUE
  45.   bit 0 -- 2.2kohm resistor  -- RED/GREEN/BLUE
  46.  
  47. ***************************************************************************/
  48.  
  49. void polepos_vh_convert_color_prom(UINT8 *palette, UINT16 *colortable, const UINT8 *color_prom)
  50. {
  51.     int i, j;
  52.  
  53.     /*******************************************************
  54.      * Color PROMs
  55.      * Sheet 15B: middle, 136014-137,138,139
  56.      * Inputs: MUX0 ... MUX3, ALPHA/BACK, SPRITE/BACK, 128V, COMPBLANK
  57.      *
  58.      * Note that we only decode the lower 128 colors because
  59.      * the upper 128 are all black and used during the
  60.      * horizontal and vertical blanking periods.
  61.      *******************************************************/
  62.     for (i = 0; i < 128; i++)
  63.     {
  64.         int bit0,bit1,bit2,bit3;
  65.  
  66.         /* Sheet 15B: 136014-0137 red component */
  67.         bit0 = (color_prom[0x000 + i] >> 0) & 1;
  68.         bit1 = (color_prom[0x000 + i] >> 1) & 1;
  69.         bit2 = (color_prom[0x000 + i] >> 2) & 1;
  70.         bit3 = (color_prom[0x000 + i] >> 3) & 1;
  71.         *(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  72.  
  73.         /* Sheet 15B: 136014-0138 green component */
  74.         bit0 = (color_prom[0x100 + i] >> 0) & 1;
  75.         bit1 = (color_prom[0x100 + i] >> 1) & 1;
  76.         bit2 = (color_prom[0x100 + i] >> 2) & 1;
  77.         bit3 = (color_prom[0x100 + i] >> 3) & 1;
  78.         *(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  79.  
  80.         /* Sheet 15B: 136014-0139 blue component */
  81.         bit0 = (color_prom[0x200 + i] >> 0) & 1;
  82.         bit1 = (color_prom[0x200 + i] >> 1) & 1;
  83.         bit2 = (color_prom[0x200 + i] >> 2) & 1;
  84.         bit3 = (color_prom[0x200 + i] >> 3) & 1;
  85.         *(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  86.     }
  87.  
  88.     /*******************************************************
  89.      * Alpha colors (colors 0x000-0x1ff)
  90.      * Sheet 15B: top left, 136014-140
  91.      * Inputs: SHFT0, SHFT1 and CHA8* ... CHA13*
  92.      *******************************************************/
  93.     for (i = 0; i < 64*4; i++)
  94.     {
  95.         int color = color_prom[0x300 + i];
  96.         colortable[0x0000 + i] = (color != 15) ? (0x020 + color) : 0;
  97.         colortable[0x0100 + i] = (color != 15) ? (0x060 + color) : 0;
  98.     }
  99.  
  100.     /*******************************************************
  101.      * View colors (colors 0x200-0x3ff)
  102.      * Sheet 13A: left, 136014-141
  103.      * Inputs: SHFT2, SHFT3 and CHA8 ... CHA13
  104.      *******************************************************/
  105.     for (i = 0; i < 64*4; i++)
  106.     {
  107.         int color = color_prom[0x400 + i];
  108.         colortable[0x0200 + i] = 0x000 + color;
  109.         colortable[0x0300 + i] = 0x040 + color;
  110.     }
  111.  
  112.     /*******************************************************
  113.      * Sprite colors (colors 0x400-0xbff)
  114.      * Sheet 14B: right, 136014-146
  115.      * Inputs: CUSTOM0 ... CUSTOM3 and DATA0 ... DATA5
  116.      *******************************************************/
  117.     for (i = 0; i < 64*16; i++)
  118.     {
  119.         int color = color_prom[0xc00 + i];
  120.         colortable[0x0400 + i] = (color != 15) ? (0x010 + color) : 0;
  121.         colortable[0x0800 + i] = (color != 15) ? (0x050 + color) : 0;
  122.     }
  123.  
  124.     /*******************************************************
  125.      * Road colors (colors 0xc00-0x13ff)
  126.      * Sheet 13A: bottom left, 136014-145
  127.      * Inputs: R1 ... R6 and CHA0 ... CHA3
  128.      *******************************************************/
  129.     for (i = 0; i < 64*16; i++)
  130.     {
  131.         int color = color_prom[0x800 + i];
  132.         colortable[0x0c00 + i] = 0x000 + color;
  133.         colortable[0x1000 + i] = 0x040 + color;
  134.     }
  135.  
  136.     /* 136014-142, 136014-143, 136014-144 Vertical position modifiers */
  137.     for (i = 0; i < 256; i++)
  138.     {
  139.         j = color_prom[0x500 + i] + (color_prom[0x600 + i] << 4) + (color_prom[0x700 + i] << 8);
  140.         polepos_vertical_position_modifier[i] = j;
  141.     }
  142.  
  143.     road_control = &color_prom[0x2000];
  144.     road_bits1 = &color_prom[0x4000];
  145.     road_bits2 = &color_prom[0x6000];
  146. }
  147.  
  148.  
  149. /***************************************************************************
  150.  
  151.   Video initialization/shutdown
  152.  
  153. ***************************************************************************/
  154.  
  155. int polepos_vh_start(void)
  156. {
  157.     /* allocate view bitmap */
  158.     view_bitmap = osd_create_bitmap(64*8, 16*8);
  159.     if (!view_bitmap)
  160.         return 1;
  161.  
  162.     /* allocate view dirty buffer */
  163.     view_dirty = malloc(64*16);
  164.     if (!view_dirty)
  165.     {
  166.         osd_free_bitmap(view_bitmap);
  167.         return 1;
  168.     }
  169.  
  170.     return 0;
  171. }
  172.  
  173. void polepos_vh_stop(void)
  174. {
  175.     osd_free_bitmap(view_bitmap);
  176.     free(view_dirty);
  177. }
  178.  
  179.  
  180. /***************************************************************************
  181.  
  182.   Sprite memory
  183.  
  184. ***************************************************************************/
  185.  
  186. READ_HANDLER( polepos_sprite_r )
  187. {
  188.     return READ_WORD(&polepos_sprite_memory[offset]);
  189. }
  190.  
  191. WRITE_HANDLER( polepos_sprite_w )
  192. {
  193.     COMBINE_WORD_MEM(&polepos_sprite_memory[offset], data);
  194. }
  195.  
  196. READ_HANDLER( polepos_z80_sprite_r )
  197. {
  198.     return polepos_sprite_r(offset << 1) & 0xff;
  199. }
  200.  
  201. WRITE_HANDLER( polepos_z80_sprite_w )
  202. {
  203.     polepos_sprite_w(offset << 1, data | 0xff000000);
  204. }
  205.  
  206.  
  207. /***************************************************************************
  208.  
  209.   Road memory
  210.  
  211. ***************************************************************************/
  212.  
  213. READ_HANDLER( polepos_road_r )
  214. {
  215.     return READ_WORD(&polepos_road_memory[offset]);
  216. }
  217.  
  218. WRITE_HANDLER( polepos_road_w )
  219. {
  220.     COMBINE_WORD_MEM(&polepos_road_memory[offset], data);
  221. }
  222.  
  223. READ_HANDLER( polepos_z80_road_r )
  224. {
  225.     return polepos_road_r(offset << 1) & 0xff;
  226. }
  227.  
  228. WRITE_HANDLER( polepos_z80_road_w )
  229. {
  230.     polepos_road_w(offset << 1, data | 0xff000000);
  231. }
  232.  
  233. WRITE_HANDLER( polepos_road_vscroll_w )
  234. {
  235.     road_vscroll = data;
  236. }
  237.  
  238.  
  239. /***************************************************************************
  240.  
  241.   View memory
  242.  
  243. ***************************************************************************/
  244.  
  245. READ_HANDLER( polepos_view_r )
  246. {
  247.     return READ_WORD(&polepos_view_memory[offset]);
  248. }
  249.  
  250. WRITE_HANDLER( polepos_view_w )
  251. {
  252.     int oldword = READ_WORD(&polepos_view_memory[offset]);
  253.     int newword = COMBINE_WORD(oldword, data);
  254.     if (oldword != newword)
  255.     {
  256.         WRITE_WORD(&polepos_view_memory[offset], newword);
  257.         if (offset < 0x800)
  258.             view_dirty[offset / 2] = 1;
  259.     }
  260. }
  261.  
  262. READ_HANDLER( polepos_z80_view_r )
  263. {
  264.     return polepos_view_r(offset << 1) & 0xff;
  265. }
  266.  
  267. WRITE_HANDLER( polepos_z80_view_w )
  268. {
  269.     polepos_view_w(offset << 1, data | 0xff000000);
  270. }
  271.  
  272. WRITE_HANDLER( polepos_view_hscroll_w )
  273. {
  274.     view_hscroll = data;
  275. }
  276.  
  277.  
  278. /***************************************************************************
  279.  
  280.   Alpha memory
  281.  
  282. ***************************************************************************/
  283.  
  284. READ_HANDLER( polepos_alpha_r )
  285. {
  286.     return READ_WORD(&polepos_alpha_memory[offset]);
  287. }
  288.  
  289. WRITE_HANDLER( polepos_alpha_w )
  290. {
  291.     int oldword = READ_WORD(&polepos_alpha_memory[offset]);
  292.     int newword = COMBINE_WORD(oldword, data);
  293.     if (oldword != newword)
  294.         WRITE_WORD(&polepos_alpha_memory[offset], newword);
  295. }
  296.  
  297. READ_HANDLER( polepos_z80_alpha_r )
  298. {
  299.     return polepos_alpha_r(offset << 1) & 0xff;
  300. }
  301.  
  302. WRITE_HANDLER( polepos_z80_alpha_w )
  303. {
  304.     polepos_alpha_w(offset << 1, data | 0xff000000);
  305. }
  306.  
  307.  
  308. /***************************************************************************
  309.  
  310.   Internal draw routines
  311.  
  312. ***************************************************************************/
  313.  
  314. static void draw_view(struct osd_bitmap *bitmap)
  315. {
  316.     struct rectangle clip = Machine->drv->visible_area;
  317.     int x, y, offs;
  318.  
  319.     /* look for dirty tiles */
  320.     for (x = offs = 0; x < 64; x++)
  321.         for (y = 0; y < 16; y++, offs++)
  322.             if (view_dirty[offs])
  323.             {
  324.                 int word = READ_WORD(&polepos_view_memory[offs * 2]);
  325.                 int code = (word & 0xff) | ((word >> 6) & 0x100);
  326.                 int color = (word >> 8) & 0x3f;
  327.  
  328.                 drawgfx(view_bitmap, Machine->gfx[1], code, color,
  329.                         0, 0, 8*x, 8*y, NULL, TRANSPARENCY_NONE, 0);
  330.                 view_dirty[offs] = 0;
  331.             }
  332.  
  333.     /* copy the bitmap */
  334.     x = -view_hscroll;
  335.     clip.max_y = 127;
  336.     copyscrollbitmap(bitmap, view_bitmap, 1, &x, 0, 0, &clip, TRANSPARENCY_NONE, 0);
  337. }
  338.  
  339. static void draw_road(struct osd_bitmap *bitmap)
  340. {
  341.     int dx = 1, dy = (bitmap->line[1] - bitmap->line[0]) * 8 / bitmap->depth;
  342.     int sx = 0, sy = 128, temp;
  343.  
  344.     /* adjust our parameters for the current orientation */
  345.     if (Machine->orientation)
  346.     {
  347.         if (Machine->orientation & ORIENTATION_SWAP_XY)
  348.         {
  349.             temp = sx; sx = sy; sy = temp;
  350.             temp = dx; dx = dy; dy = temp;
  351.         }
  352.         if (Machine->orientation & ORIENTATION_FLIP_X)
  353.         {
  354.             sx = bitmap->width - 1 - sx;
  355.             if (!(Machine->orientation & ORIENTATION_SWAP_XY)) dx = -dx;
  356.             else dy = -dy;
  357.         }
  358.         if (Machine->orientation & ORIENTATION_FLIP_Y)
  359.         {
  360.             sy = bitmap->height - 1 - sy;
  361.             if (Machine->orientation & ORIENTATION_SWAP_XY) dx = -dx;
  362.             else dy = -dy;
  363.         }
  364.     }
  365.  
  366.     /* 8-bit case */
  367.     if (bitmap->depth == 8)
  368.         draw_road_core_8(bitmap, sx, sy, dx, dy);
  369.     else
  370.         draw_road_core_16(bitmap, sx, sy, dx, dy);
  371. }
  372.  
  373. static void draw_sprites(struct osd_bitmap *bitmap)
  374. {
  375.     UINT16 *posmem = (UINT16 *)&polepos_sprite_memory[0x700];
  376.     UINT16 *sizmem = (UINT16 *)&polepos_sprite_memory[0xf00];
  377.     int i;
  378.  
  379.     for (i = 0; i < 64; i++, posmem += 2, sizmem += 2)
  380.     {
  381.         const struct GfxElement *gfx = Machine->gfx[(sizmem[0] & 0x8000) ? 3 : 2];
  382.         int vpos = (~posmem[0] & 0x1ff) + 4;
  383.         int hpos = (posmem[1] & 0x3ff) - 0x40;
  384.         int vsize = ((sizmem[0] >> 8) & 0x3f) + 1;
  385.         int hsize = ((sizmem[1] >> 8) & 0x3f) + 1;
  386.         int code = sizmem[0] & 0x7f;
  387.         int hflip = sizmem[0] & 0x80;
  388.         int color = sizmem[1] & 0x3f;
  389.  
  390.         if (vpos >= 128) color |= 0x40;
  391.         drawgfxzoom(bitmap, gfx,
  392.                  code, color, hflip, 0, hpos, vpos,
  393.                  &Machine->drv->visible_area, TRANSPARENCY_COLOR, 0, hsize << 11, vsize << 11);
  394.     }
  395. }
  396.  
  397. static void draw_alpha(struct osd_bitmap *bitmap)
  398. {
  399.     int x, y, offs, in;
  400.  
  401.     for (y = offs = 0; y < 32; y++)
  402.         for (x = 0; x < 32; x++, offs++)
  403.         {
  404.             int word = READ_WORD(&polepos_alpha_memory[offs * 2]);
  405.             int code = (word & 0xff) | ((word >> 6) & 0x100);
  406.             int color = (word >> 8) & 0x3f;    /* 6 bits color */
  407.  
  408.             if (y >= 16) color |= 0x40;
  409.             drawgfx(bitmap, Machine->gfx[0],
  410.                      code, color, 0, 0, 8*x, 8*y,
  411.                      &Machine->drv->visible_area, TRANSPARENCY_COLOR, 0);
  412.         }
  413.  
  414.     /* Now draw the shift if selected on the fake dipswitch */
  415.     in = readinputport( 0 );
  416.  
  417.     if ( in & 8 ) {
  418.         if ( ( in & 2 ) == 0 ) {
  419.             /* L */
  420.             drawgfx(bitmap, Machine->gfx[0],
  421.                      0x15, 0, 0, 0, 30*8-1, 29*8,
  422.                      &Machine->drv->visible_area, TRANSPARENCY_PEN, 0);
  423.             /* O */
  424.             drawgfx(bitmap, Machine->gfx[0],
  425.                      0x18, 0, 0, 0, 31*8-1, 29*8,
  426.                      &Machine->drv->visible_area, TRANSPARENCY_PEN, 0);
  427.         } else {
  428.             /* H */
  429.             drawgfx(bitmap, Machine->gfx[0],
  430.                      0x11, 0, 0, 0, 30*8-1, 29*8,
  431.                      &Machine->drv->visible_area, TRANSPARENCY_PEN, 0);
  432.             /* I */
  433.             drawgfx(bitmap, Machine->gfx[0],
  434.                      0x12, 0, 0, 0, 31*8-1, 29*8,
  435.                      &Machine->drv->visible_area, TRANSPARENCY_PEN, 0);
  436.         }
  437.     }
  438. }
  439.  
  440.  
  441. /***************************************************************************
  442.  
  443.   Master refresh routine
  444.  
  445. ***************************************************************************/
  446.  
  447. void polepos_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh)
  448. {
  449.     draw_view(bitmap);
  450.     draw_road(bitmap);
  451.     draw_sprites(bitmap);
  452.     draw_alpha(bitmap);
  453. }
  454.  
  455.  
  456. /***************************************************************************
  457.  
  458.   Road drawing generators
  459.  
  460. ***************************************************************************/
  461.  
  462. #define ROAD_CORE_INCLUDE
  463.  
  464. #define NAME draw_road_core_8
  465. #define TYPE UINT8
  466. #include "polepos.c"
  467. #undef TYPE
  468. #undef NAME
  469.  
  470. #define NAME draw_road_core_16
  471. #define TYPE UINT16
  472. #include "polepos.c"
  473. #undef TYPE
  474. #undef NAME
  475.  
  476. #else
  477.  
  478. /***************************************************************************
  479.  
  480.   Road drawing routine
  481.  
  482. ***************************************************************************/
  483.  
  484. static void NAME(struct osd_bitmap *bitmap, int sx, int sy, int dx, int dy)
  485. {
  486.     TYPE *base = &((TYPE *)bitmap->line[sy])[sx];
  487.     int x, y, i;
  488.  
  489.     /* loop over the lower half of the screen */
  490.     for (y = 128; y < 256; y++, base += dy)
  491.     {
  492.         int xoffs, yoffs, roadpal;
  493.         UINT16 *colortable;
  494.         TYPE *dest;
  495.  
  496.         /* first add the vertical position modifier and the vertical scroll */
  497.         yoffs = ((polepos_vertical_position_modifier[y] + road_vscroll) >> 2) & 0x3fe;
  498.  
  499.         /* then use that as a lookup into the road memory */
  500.         roadpal = READ_WORD(&polepos_road_memory[yoffs]) & 15;
  501.  
  502.         /* this becomes the palette base for the scanline */
  503.         colortable = &Machine->remapped_colortable[0x1000 + (roadpal << 6)];
  504.  
  505.         /* now fetch the horizontal scroll offset for this scanline */
  506.         xoffs = READ_WORD(&polepos_road_memory[0x700 + (y & 0x7f) * 2]) & 0x3ff;
  507.  
  508.         /* the road is drawn in 8-pixel chunks, so round downward and adjust the base */
  509.         /* note that we assume there is at least 8 pixels of slop on the left/right */
  510.         dest = base - (xoffs & 7) * dx;
  511.         xoffs &= ~7;
  512.  
  513.         /* loop over 8-pixel chunks */
  514.         for (x = 0; x < 256 / 8 + 1; x++, xoffs += 8)
  515.         {
  516.             /* if the 0x200 bit of the xoffset is set, a special pin on the custom */
  517.             /* chip is set and the /CE and /OE for the road chips is disabled */
  518.             if (xoffs & 0x200)
  519.             {
  520.                 /* in this case, it looks like we just fill with 0 */
  521.                 for (i = 0; i < 8; i++, dest += dx)
  522.                     *dest = colortable[0];
  523.             }
  524.  
  525.             /* otherwise, we clock in the bits and compute the road value */
  526.             else
  527.             {
  528.                 /* the road ROM offset comes from the current scanline and the X offset */
  529.                 int romoffs = ((y & 0x07f) << 6) + ((xoffs & 0x1ff) >> 3);
  530.  
  531.                 /* fetch the current data from the road ROMs */
  532.                 int control = road_control[romoffs];
  533.                 int bits1 = road_bits1[romoffs];
  534.                 int bits2 = road_bits2[(romoffs & 0xfff) | ((romoffs >> 1) & 0x800)];
  535.  
  536.                 /* extract the road value and the carry-in bit */
  537.                 int roadval = control & 0x3f;
  538.                 int carin = control >> 7;
  539.  
  540.                 /* draw this 8-pixel chunk */
  541.                 for (i = 0; i < 8; i++, dest += dx, bits1 <<= 1, bits2 <<= 1)
  542.                 {
  543.                     int bits = ((bits1 >> 7) & 1) + ((bits2 >> 6) & 2);
  544.                     if (!carin && bits) bits++;
  545.                     *dest = colortable[roadval & 0x3f];
  546.                     roadval += bits;
  547.                 }
  548.             }
  549.         }
  550.     }
  551. }
  552.  
  553. #endif
  554.